import os, requests, logging, time
from flask import Flask
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, WebDriverException
from threading import Thread
from apscheduler.schedulers.background import BackgroundScheduler

# 配置项（保持不变）
WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=b0bcfe46-3aa1-4071-afd5-da63be5a8644"
TARGET_URL  = "https://www.d2-trade.com/query/terror-zones"
#HOUR_DELAY_SECONDS = 59
HALF_HOUR_DELAY_SECONDS = 0
MAX_RETRIES = 3
LOAD_TIMEOUT = 150
ELEMENT_WAIT_TIMEOUT = 40
RETRY_INTERVAL = 5
CHROMEDRIVER_PATH = "/root/.wdm/drivers/chromedriver/linux64/141.0.7390.107/chromedriver"

# 日志配置（保持不变）
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s",
    handlers=[logging.FileHandler("app.log"), logging.StreamHandler()]
)
logger = logging.getLogger(__name__)

app = Flask(__name__)
scheduler = BackgroundScheduler()

def fetch_terror_info():
    options = Options()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--disable-gpu")
    options.add_argument("--window-size=1920,1080")
    options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36")
    options.add_argument("--blink-settings=imagesEnabled=false")
    options.add_argument("--disable-extensions")
    options.add_argument("--disable-plugins")
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option("useAutomationExtension", False)
    options.add_experimental_option("prefs", {
        "profile.default_content_setting_values.cookies": 1,
        "profile.cookie_controls_mode": 0
    })

    driver = None
    retry_count = 0
    
    while retry_count < MAX_RETRIES:
        try:
            chrome_service = Service(executable_path=CHROMEDRIVER_PATH)
            driver = webdriver.Chrome(options=options, service=chrome_service)
            driver.set_page_load_timeout(LOAD_TIMEOUT)
            driver.get("https://www.d2-trade.com/")
            time.sleep(2)
            driver.get(TARGET_URL)

            # 关键修复：先等待元素存在，再验证文本非空（避免返回bool值）
            # 1. 等待当前区域元素出现
            WebDriverWait(driver, ELEMENT_WAIT_TIMEOUT).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, ".current-zone-content .zone-info h3"))
            )
            # 2. 验证当前区域文本非空
            current_zone_elem = WebDriverWait(driver, ELEMENT_WAIT_TIMEOUT).until(
                lambda x: x.find_element(By.CSS_SELECTOR, ".current-zone-content .zone-info h3") 
                if x.find_element(By.CSS_SELECTOR, ".current-zone-content .zone-info h3").text.strip() != "" 
                else False
            )

            # 3. 等待下一区域元素出现
            WebDriverWait(driver, ELEMENT_WAIT_TIMEOUT).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, ".upcoming-zones-section .next-zone .zone-info h3"))
            )
            # 4. 验证下一区域文本非空
            next_zone_elem = WebDriverWait(driver, ELEMENT_WAIT_TIMEOUT).until(
                lambda x: x.find_element(By.CSS_SELECTOR, ".upcoming-zones-section .next-zone .zone-info h3") 
                if x.find_element(By.CSS_SELECTOR, ".upcoming-zones-section .next-zone .zone-info h3").text.strip() != "" 
                else False
            )

            # 提取文本（修复后可正常调用.text属性）
            current_zone = current_zone_elem.text.strip()
            current_time_elem = driver.find_element(By.CSS_SELECTOR, ".current-zone-content .zone-timer .timer-value")
            current_time = f"剩余 {current_time_elem.text.strip()}" if current_time_elem.text.strip() != "" else "剩余 未知"

            next_zone = next_zone_elem.text.strip()
            next_time_elem = driver.find_element(By.CSS_SELECTOR, ".upcoming-zones-section .next-zone .schedule-item .value")
            next_time = next_time_elem.text.strip() if next_time_elem.text.strip() != "" else "01/01 00:00"

            # 验证区域名称有效性
            if not current_zone or len(current_zone) < 2:
                raise ValueError(f"当前区域名称无效: {current_zone}")
            if not next_zone or len(next_zone) < 2:
                raise ValueError(f"下一区域名称无效: {next_zone}")

            logger.info(f"提取成功 - 当前: {current_zone} ({current_time}), 下一个: {next_zone} ({next_time})")
            return current_zone, current_time, next_zone, next_time

        except TimeoutException:
            retry_count += 1
            logger.warning(f"第{retry_count}次重试 - 区域名称未加载完成（超时）")
            if retry_count >= MAX_RETRIES:
                logger.error("达到最大重试次数，抓取失败")
                return None, None, None, None
            time.sleep(RETRY_INTERVAL)
        except ValueError as e:
            retry_count += 1
            logger.warning(f"第{retry_count}次重试 - {str(e)}")
            if retry_count >= MAX_RETRIES:
                logger.error("达到最大重试次数，抓取失败")
                return None, None, None, None
            time.sleep(RETRY_INTERVAL)
        except WebDriverException as e:
            logger.error(f"WebDriver异常: {str(e)}", exc_info=True)
            return None, None, None, None
        except Exception as e:
            logger.error(f"抓取失败: {str(e)}", exc_info=True)
            return None, None, None, None
        finally:
            if driver:
                try:
                    driver.quit()
                except Exception as e:
                    logger.warning(f"关闭浏览器失败: {str(e)}")

# 推送函数（保持不变）
def send_wecom_message(current, current_time, next, next_time):
    current = current or "暂无当前区域"
    next = next or "暂无下一区域"
    content = f"{current}▶{next}"
    retry_count = 3
    
    for i in range(retry_count):
        try:
            rsp = requests.post(
                WEBHOOK_URL,
                json={"msgtype": "text", "text": {"content": content}},
                timeout=10
            )
            rsp.raise_for_status()
            logger.info(f"推送成功: {content}，响应：{rsp.json()}")
            return
        except Exception as e:
            logger.error(f"第{i+1}次推送失败: {str(e)}")
            if i == retry_count - 1:
                logger.error("达到最大重试次数，推送失败")

# 定时任务和路由函数（保持不变）
def scheduled_push():
    logger.info(f"开始定时推送")
    _push_real_data()

def _push_real_data():
    try:
        current, current_time, next, next_time = fetch_terror_info()
        if current or next:
            send_wecom_message(current, current_time, next, next_time)
        else:
            logger.warning("无有效数据，发送默认消息")
            requests.post(
                WEBHOOK_URL,
                json={"msgtype": "text", "text": {"content": "暂无数据▶暂无数据"}},
                timeout=5
            )
    except Exception as e:
        logger.exception("推送异常")
        try:
            requests.post(
                WEBHOOK_URL,
                json={"msgtype": "text", "text": {"content": "后台异常▶后台异常"}},
                timeout=5
            )
        except Exception as e:
            logger.error(f"异常通知推送失败: {str(e)}")

@app.route("/")
def index():
    Thread(target=_push_real_data, daemon=True).start()
    return "d2-trade 恐怖区域服务运行中", 200

if __name__ == "__main__":
    scheduler.add_job(
        scheduled_push,
        trigger="cron",
        second=0,
        minute=2,
        hour="*",
        timezone="Asia/Shanghai"
    )
    scheduler.add_job(
        scheduled_push,
        trigger="cron",
        second=HALF_HOUR_DELAY_SECONDS,
        minute=30,
        hour="*",
        timezone="Asia/Shanghai"
    )
    scheduler.start()
    logger.info(f"定时任务已启动，将在每天整点后120秒和半点推送")
    port = int(os.environ.get("PORT", 10000))
    app.run(host="0.0.0.0", port=port)
